package service

import (
	"advertising/config/mysql"
	"advertising/config/redis"
	"advertising/internal/dal"
	"advertising/internal/dao"
	"advertising/internal/define"
	"advertising/internal/models"
	"context"
	"strconv"
	"time"

	"192.168.1.75/go-pkg/timewheel"
)

var tw *timewheel.TimeWheel

// 通过时间轮，定时更新推广统计值到mysql
func init() {
	tw = timewheel.New(time.Second, 60, func(data interface{}) {
		rdb := redis.NewDB()
		ctx, cancel := context.WithTimeout(context.Background(), time.Second*5)
		defer cancel()
		if promotionID, ok := data.(string); ok {
			val, _ := rdb.Get(ctx, define.RedisPromotionCount+promotionID).Result()
			count, _ := strconv.ParseInt(val, 10, 64)
			p := dal.Use(mysql.NewDB()).PromotionCount
			record, _ := p.WithContext(ctx).Where(p.ID.Eq(promotionID)).Take()
			// 无效的推广id，结束
			if record == nil {
				return
			}
			// redis 存储丢失或落后，则同步mysql的计数
			if count == 0 || count < record.Count {
				rdb.Set(ctx, define.RedisPromotionCount+promotionID, record.Count, time.Hour*24*30)
				// mysql的计数滞后redis，则更新计数
			} else if record.Count < int64(count) {
				p.WithContext(ctx).Where(p.ID.Eq(promotionID)).Update(p.Count, count)
			}
		}
	})
	tw.Start()
}

type PromotionCount struct{}

// Increase 统计自增
func (PromotionCount) Increase(
	ctx context.Context,
	promotionID string,
) {
	dao.PromotionCount{}.Increase(promotionID)
	// 延迟任务，减少mysql的压力
	tw.AddTimer(promotionID, time.Second*5, promotionID)
}

// GetName 获取推广名称
func (PromotionCount) Detail(
	ctx context.Context,
	promotionID string,
) (*models.PromotionCount, error) {
	return dao.PromotionCount{}.Detail(ctx, dal.Q, promotionID)
}
